package com.flame.shapeville.factory;

import com.flame.shapeville.service.CourseService;
import com.flame.shapeville.service.ExerciseService;
import com.flame.shapeville.service.TaskService;
import com.flame.shapeville.service.UserService;

import java.util.HashMap;
import java.util.Map;

/**
 * A simple implementation of a bean factory that manages singleton instances of core services.
 * <p>
 * This class provides a centralized way to access and manage service beans such as
 * {@link UserService}, {@link TaskService}, etc., using a key-value mapping.
 *
 * @author Flame Dev Team
 * @version 1.0
 * @since 2025-05-01
 */
public class BeanFactory {
    /**
     * Internal map used to store the bean instances.
     * Keys are bean names (e.g., "userService"), values are the corresponding service instances.
     */
    private static Map<String, Object> factory;

    /**
     * Static block to initialize the factory with default service beans.
     * <p>
     * Initializes and registers:
     * - {@link UserService}
     * - {@link TaskService}
     * - {@link ExerciseService}
     * - {@link CourseService}
     */
    static {
        UserService userService = new UserService();
        factory = new HashMap<>();
        factory.put("userService", userService);
        factory.put("taskService", new TaskService());
        factory.put("exerciseService", new ExerciseService());
        factory.put("courseService", new CourseService());
    }

    /**
     * Retrieves a bean instance from the factory by its name.
     *
     * @param name the name of the bean to retrieve
     * @return the bean object associated with the given name, or null if not found
     */
    public static Object getBean(String name) {
        return factory.get(name);
    }

    /**
     * Registers or replaces a bean in the factory with the specified name.
     *
     * @param name  the name under which the bean should be registered
     * @param bean  the bean instance to register
     */
    public static void setBean(String name, Object bean) {
        factory.put(name, bean);
    }
}
